package com.panda.quartz.util;

import com.alibaba.fastjson.JSONObject;
import org.springframework.context.ApplicationContext;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class ServiceUtils {
    /**
     * 执行指定的service
     * @param context
     * @param dto
     *            数据对象
     * @param serviceName
     *            类名
     * @param methodName
     *            方法名
     * @param cls
     *            参数列表 例如 new Class[] { 参数类型.class }
     * @return
     */
    public static Object invokeMethod(Object[] obj, String serviceName, String methodName) {
        ApplicationContext context = SpringContextHolder.getApplicationContext();
        Object result = null;
        Class<? extends Object> class1 = context.getBean(serviceName).getClass();
        Method[] ms = class1.getDeclaredMethods();
        Class<?>[] parameterTypes = null;
        for (Method m : ms) {
            if (methodName.equals(m.getName())) {
                parameterTypes = m.getParameterTypes();
                break;
            }
        }
        Method mh = ReflectionUtils.findMethod(context.getBean(serviceName).getClass(), methodName, parameterTypes);
        result = ReflectionUtils.invokeMethod(mh, context.getBean(serviceName), obj);
        return result;
    }

    /**
     * 获取service关联的entity类
     *
     * @return
     * @throws ClassNotFoundException
     */
    public static Class getAssociateEntityClass(ApplicationContext context, String serviceName) {
        Class<? extends Object> clz = context.getBean(serviceName).getClass();
        Type genericSuperclass = clz.getGenericSuperclass();
        // 获取到Service中的泛型，如果父类没有则取父类的父类。一直往上
        while(!(genericSuperclass instanceof ParameterizedType)){
            clz = clz.getSuperclass();
            genericSuperclass = clz.getGenericSuperclass();
        }
        Type[] actualTypeArguments = ((ParameterizedType) genericSuperclass).getActualTypeArguments();
        Class entity = (Class)actualTypeArguments[0] ;
        return entity;
    }
}
